<?php

namespace App\Repository;

use App\Models\Anchor\AnchorAuthorModel;
use App\Models\Anchor\AnchorWorksModel;
use App\Models\CommissionReturn\CommissionReturnLogsModel;
use App\Models\CommissionReturn\CommissionReturnModel;
use App\Models\Orders\OrdersModel;
use App\Models\Orders\OrdersUserModel;
use App\Models\Rebate\RebateLogsModel;
use App\Models\Rebate\RebateModel;
use App\Repository\Rebate\RebateLogsRepository;
use Illuminate\Support\Facades\Cache;

class ChatRepository extends BaseRepository
{
    public function __construct()
    {

        parent::__construct();
    }

    public function index($params = [], $page = 1, $limit = 10)
    {
        switch ($params['dataN']) {
            case 5:
                $data = $this->data5($params);
                break;
            case 4:
                $data = $this->data4($params);
                break;
            case 3:
                $data = $this->data3($params);
                break;
            case 2:
                $data = $this->data2($params);
                break;
            default:
                $data = $this->data1($params);
                break;
        }
        return $data;
    }

    protected function getWhereArray($params = [])
    {
        $loginUserShopId = $params['user']['shop_id'];

        $ModelAnchorAuthor = new AnchorAuthorModel();
        $where = [];
        //创建时间条件
        if (isset($params['dateRange']) && !empty($params['dateRange'])) {
            $params['dateRange'] = [date('Y-m-d', strtotime($params['dateRange'][0])), date('Y-m-d', strtotime($params['dateRange'][1])) . ' 23:59:59'];
            $where['between']['a.activat_at'] = $params['dateRange'];
        } else {
            $where['between']['a.activat_at'] = [date('Y-m-d'), date('Y-m-d H:i:s')];
        }
//        客服条件
        if (isset($params['service_user_id']) && !empty($params['service_user_id'])) {
            if (is_array($params['service_user_id'])) {
                if (count($params['service_user_id']) > 1) {
                    $where['in']['a.service_user_id'] = $params['service_user_id'];
                } else {
                    $where['eq']['a.service_user_id'] = $params['service_user_id'][0];
                }
            } else {
                $where['eq']['a.service_user_id'] = $params['service_user_id'];
            }
        }
//        分销商
        if (isset($params['shop_id']) && !empty($params['shop_id'])) {
            if (is_array($params['shop_id'])) {
                if (count($params['shop_id']) > 1) {
                    $where['in']['a.shop_id'] = $params['shop_id'];
                } else {
                    $where['eq']['a.shop_id'] = $params['shop_id'][0];
                }
            } else {
                $where['eq']['a.shop_id'] = $params['shop_id'];
            }
        } else {
            $where['eq']['a.shop_id'] = $loginUserShopId;
        }
//        商品条件
        if (isset($params['goods_id']) && !empty($params['goods_id'])) {
            if (is_array($params['goods_id'])) {
                if (count($params['goods_id']) > 1) {
                    $where['in']['a.goods_id'] = $params['goods_id'];
                } else {
                    $where['eq']['a.goods_id'] = $params['goods_id'][0];
                }
            } else {
                $where['eq']['a.goods_id'] = $params['goods_id'];
            }
        }
        if (isset($params['product_id']) && !empty($params['product_id'])) {
            if (is_array($params['product_id'])) {
                if (count($params['product_id']) > 1) {
                    $where['in']['a.product_id'] = $params['product_id'];
                } else {
                    $where['eq']['a.product_id'] = $params['product_id'][0];
                }
            } else {
                $where['eq']['a.product_id'] = $params['product_id'];
            }
        }
//        订单来源
        if (isset($params['source']) && !empty($params['source'])) {
            if (is_array($params['source'])) {
                if (count($params['source']) > 1) {
                    $where['in']['b.source'] = $params['source'];
                } else {
                    $where['eq']['b.source'] = $params['source'][0];
                }
            } else {
                $where['eq']['b.source'] = $params['source'];
            }
        }
//        主播要特殊处理
        if (isset($params['anchor_id']) && !empty($params['anchor_id'])) {
            $anchorWhere = [];
            if (is_array($params['anchor_id'])) {
                if (count($params['anchor_id']) > 1) {
                    $anchorWhere['in']['anchor_id'] = $params['anchor_id'];
                } else {
                    $anchorWhere['anchor_id'] = $params['anchor_id'][0];
                }
            } else {
                $anchorWhere['anchor_id'] = $params['anchor_id'];
            }

            $authorIds = [];
            foreach ($ModelAnchorAuthor->searchWhere($anchorWhere)->select(['author_id'])->cursor() as $row) {
                $authorIds[] = $row->author_id;
            }
        }
//        达人条件
        if (isset($params['author_id']) && !empty($params['author_id'])) {
//            上面的主播里是否有查询到达人
            if (!isset($authorIds)) {
                $authorIds = [];
            }
            if (is_array($params['author_id'])) {
                $authorIds = array_merge($authorIds, $params['author_id']);
            } else {
                $authorIds[] = $params['author_id'];
            }
            if (count($authorIds) > 1) {
                $where['in']['b.author_id'] = $authorIds;
            } else {
                $where['eq']['b.author_id'] = $authorIds[0];
            }
        }
        return $where;
    }

    // 同一个页里面查询条件都是一样的,所以它生成的key也是一样的
    protected function getWhereCacheKey($whereArray = [])
    {
        return md5(serialize($whereArray));
    }

    protected function getWhereOrdersData($where, $fields = [])
    {
        if (empty($fields)) {
            $fields = [
                'a.id',
                'a.ordersno',
                'a.status',
                'a.first_status',
                'a.first_status_at',
                'a.first_money',
                'a.card_status',
                'a.goods_name',
                'a.goods_id',
                'a.product_id',
                'a.product_name',
                'a.is_online',
                'a.rebate_status',
                'a.rebate_user_id',
                'a.passing_money',
                'b.sku_number'
            ];
        }
        $cacheFile = $this->getWhereCacheKey($where);
        $ModelOrders = new OrdersModel();
        $ModelOrdersUser = new OrdersUserModel();
        $rows = Cache::get($cacheFile);
        if (empty($rows)) {
            foreach ($ModelOrders->from($ModelOrders->getTable(), 'a')
                         ->leftJoin($ModelOrdersUser->getTable() . ' AS b', 'a.ordersno', '=', 'b.orderno')
                         ->searchWhere($where)
                         ->select($fields)
                         ->orderByDesc('a.id')
                         ->cursor() as $row) {
                $rows[$row['ordersno']] = $row;
            }
//            echo $this->getLastSql();
            // 只缓存订单表数据
            Cache::put($cacheFile, $rows, 120);
        }
        return $rows;
    }

    public function data1($params = [])
    {
        $where = $this->getWhereArray($params);
        $count = 0;
        $data1 = [
            'total' => 0,
            'tr' => 0,
//            提交订单
            'a' => 0,
            'ar' => 0,
//            发货订单
            'b' => 0,
            'br' => 0,
//            跟进中
            'c' => 0,
            'cr' => 0,
//            失败订单
            'd' => 0,
            'dr' => 0,
//            激活订单
            'e' => 0,
            'er' => 0,
//            充值订单
            'f' => 0,
            'fr' => 0,
//            充值达标
            'g' => 0,
            'gr' => 0
        ];

//        $page = 1;
//        $limit = 500;
        $orderRows = $this->getWhereOrdersData($where);
        $authorIds = [];
        if (empty($orderRows)) {
            return $this->returnMsg(200, '无订单数据', $data1, $count);
        }

        foreach ($orderRows as $row) {
            $authorIds[] = $row->author_id;
            $data1['total'] += 1;
//排除50 => '异常单',51 => '取消单',60 => '失败单',0 => '提交中',都算提交上游
            if (!in_array($row->status, [0, 50, 51, 60])) {
//                    提交上游
                $data1['a'] += 1;
            }
            //已发货
            if (in_array($row->status, [20, 30, 40, 41])) {
                $data1['b'] += 1;
            }
            // 失败订单
            if (in_array($row->status, [50, 51, 60])) {
                $data1['d'] += 1;
            }
//                    充值达标
            if (intval($row['passing_money']) > 0 && (intval($row['first_money']) >= intval($row['passing_money']))) {
                $data1['g'] += 1;
            }
//                    激活订单
            if ($row['activat_status'] == 1) {
                $data1['e'] += 1;
            }
//                    已充值订单
            if (intval($row['first_status']) == 1) {
                $data1['f'] += 1;
            }
//                    跟进中
            if ($row['service_user_id'] >= 0) {
                $data1['c'] += 1;
            }
        }
        $data1['cost'] = $this->sumAnchorCost($params, $authorIds);
        //缓存条件查询到的订单数据
        return $this->returnMsg(200, '查询成功', $data1, $count);
    }

    //返费报表数据
    public function data2($params = [])
    {
        $where = $this->getWhereArray($params);
        $cacheFile = $this->getWhereCacheKey($where);
        $orderRows = Cache::get($cacheFile);
        Cache::forget($cacheFile);
        //分析订单中哪些商品已返,哪些没返
        $data = [
            //预计返费订单数量
            'a' => 0,
            //预计返费订单金额
            'b' => 0,
            //已返费订单数量
            'c' => 0,
            //已返费订单金额
            'd' => 0,
            //未返费订单数量
            'e' => 0,
            //未返费订单金额
            'f' => 0,
            //每个产品订单数量
            'g' => []
        ];
        if (empty($orderRows)) {
            $orderRows = $this->getWhereOrdersData($where);
            if (empty($orderRows)) {
                return $this->returnMsg(200, '无订单数据', $data, 0);
            }
        }
//        print_r($orderRows);
        //返费规则与已返数据
        $ModelRebate = new RebateModel();
        $rebateRows = [];
        $productIds = [];
        foreach ($ModelRebate->with(["rules" => function ($query) {
            $query->select(['rebate_id', 'month', 'money']);
        }])->select(['id', 'product_id', 'effective_at', 'instantly_money'])->where(['status' => 0])->get() as $row) {
            $rebateRows[$row['product_id']] = $row->toArray();
            $productIds[] = $row['product_id'];
        };
//        print_r($rebateRows);
        $productIds = array_unique($productIds);
        //已返费数据
        $ModelRebateLogs = new RebateLogsModel();
        $logsRows = [];
        foreach ($ModelRebateLogs->whereIn('product_id', $productIds)->select(['product_id', 'ordersno', 'type', 'money', 'month'])->cursor() as $row) {
            $logsRows[$row['ordersno']] = $row;
        }
        $RepositoryLogs = new RebateLogsRepository();

        foreach ($orderRows as $row) {
            $productId = $row['product_id'];
            $rebateItem = $rebateRows[$productId] ?? null;
            // 没有设置返费的产品
            if (empty($rebateItem)) {
                continue;
            }
            // 规则生效时间小于首充时间的不算
            if (strtotime($row['first_status_at']) < strtotime($rebateItem['effective_at'])) {
                continue;
            }
            // 没有设计产品返费规则
            if (!isset($rebateRows[$productId])) {
                continue;
            }
            $ordersno = $row['ordersno'];
            $monthN = $RepositoryLogs->computeT($row['first_status_at'], $params['dateRange'][1] ?? time());
            $maxMonthN = 0;
            $monthMoney = [];
            if (!empty($rebateItem['rules'])) {
                foreach ($rebateItem['rules'] as $r) {
                    if ($r['month'] > $maxMonthN) {
                        $maxMonthN = $r['month'];
                    }
                    $monthMoney[$r['month']] = $r['money'];
                }
            }
            if (isset($logsRows[$ordersno])) {
                // 当前订单是T几返,超出规则设计的月份不返
                if ($logsRows[$ordersno]['type'] == 0) {
                    //已立返金额
                    $data['c'] += 1;
                    $data['d'] += $logsRows[$ordersno]['money'];
                } else {
                    //规则返金额,规则最大月份小于等于订单要返的月份才可以返
                    if ($maxMonthN <= $monthN) {
                        $data['c'] += 1;
                        $data['d'] += $logsRows[$ordersno]['money'];
                    }
                }
            } else {
                //未返订单数据
                if ($rebateItem['instantly_money'] > 0) {
                    //立返金额
                    $data['e'] += 1;
                    $data['f'] += $rebateItem['instantly_money'];
                }
                //规则返金额
                if ($maxMonthN <= $monthN && !empty($monthMoney[$monthN]['money'])) {
                    $data['e'] += 1;
                    $data['f'] += $monthMoney[$monthN]['money'];
                }
            }
            //按产品来做报表,每个产品的订单数
            if (isset($data['g']['total'])) {
                $data['g']['total'] += 1;
            } else {
                $data['g']['total'] = 1;
            }
            if (isset($data['g'][$productId])) {
                $data['g'][$productId]['count'] += 1;
            } else {
                $data['g'][$productId]['name'] = $row['product_name'];
                $data['g'][$productId]['count'] = 1;
            }
        }
        // 总共要返
        $data['a'] = $data['c'] + $data['e'];
        $data['b'] = $data['d'] + $data['f'];
        return $this->returnMsg(200, '无订单数据', $data, 0);
    }

    //在线情况
    public function data3($params = [])
    {
        $ModelOrders = new OrdersModel();
        $cacheFile = 'chat_total_online';
        $data = Cache::get($cacheFile);
        if (empty($data)) {
            $onlineWhere = [];
            $onlineWhere['eq']['is_online'] = 1;
            $onlineTotal = $ModelOrders->searchWhere($onlineWhere)->count('id');
            $offlineWhere = [];
            $offlineWhere['neq']['is_online'] = 1;
            $offlineTotal = $ModelOrders->searchWhere($offlineWhere)->count('id');
            $data = [
                'a' => $onlineTotal,
                'b' => $offlineTotal
            ];
            $data['total'] = $onlineTotal + $offlineTotal;
            $data['rate'] = 0;
            if ($data['total'] > 0) {
                $data['rate'] = round($onlineTotal / $data['total'] * 100, 1);
            }
            Cache::put($cacheFile, $data, 380);
        }
        return $this->returnMsg(200, '无订单数据', $data, 0);
    }

    //产品在网情况
    public function data4($params = [])
    {
        $productId = $params['online_product_id'] ?? 0;
//        $productId = 121;
        // 激活月期
        $activatMonth = $params['online_activat_ym'] ?? date('Ym', strtotime("-1 year"));
        $ModelLogs = new CommissionReturnLogsModel();
        $where = [];
        $where['eq']['product_id'] = $productId;
        $where['eq']['activat_month'] = $activatMonth;
//        $where['egt']['billing_at'] = date('Y-m-d', strtotime("-2 year"));
        $feilds = ['online', 'online_t'];
        $data = [
            'onlineTotal' => 0,
            'onlineData' => [],
            'offlineTotal' => 0,
            'offlineData' => []
        ];
        // 初始化
        for ($i = 1; $i <= 24; $i++) {
            $tn = 'T' . $i;
            $data['onlineData'][$tn] = 0;
            $data['offlineData'][$tn] = 0;
            $data['onlineRate'][$tn] = 0;
            $data['offlineRate'][$tn] = 0;
        }
        foreach ($ModelLogs->searchWhere($where)->select($feilds)->cursor() as $row) {
            $tn = 'T' . $row['online_t'];
            if ($row['online'] == 1) {
                $data['onlineTotal'] += 1;
                if (!isset($data['onlineData'][$tn])) {
                    $data['onlineData'][$tn] = 1;
                } else {
                    $data['onlineData'][$tn] += 1;
                }
            } else {
                $data['offlineTotal'] += 1;
                if (!isset($data['offlineData'][$tn])) {
                    $data['offlineData'][$tn] = 1;
                } else {
                    $data['offlineData'][$tn] += 1;
                }
            }
            //计算在线率
            $rate = round($data['onlineData'][$tn] / ($data['onlineData'][$tn] + ($data['offlineData'][$tn] ?? 0)) * 100, 2);
            $data['onlineRate'][$tn] = $rate;
            //计算在线率
            $rate = round($data['offlineData'][$tn] / ($data['offlineData'][$tn] + ($data['onlineData'][$tn] ?? 0)) * 100, 2);
            $data['offlineRate'][$tn] = $rate;
        }
        return $this->returnMsg(200, '无订单数据' . $this->getLastSql(), $data, 0);
    }

    // 产品佣金
    public function data5($params = [])
    {
        $dateRange = $params['dateRange'];
        if (empty($dateRange)) {
            $dateRange = [date('Y-m-d H:i:s', strtotime('-3 month')), date('Y-m-d')];
        }
//        $dateRange = ['2023-01-01', '2024-01-01'];
        $billingStart = date('Ym', strtotime($dateRange[0]));
        $billingEnd = date('Ym', strtotime($dateRange[1]));
        $where = [];
        $where['raw'][] = "billing>=" . $billingStart . " and billing<=" . $billingEnd;
//        $cacheFile = 'data5' . $this->getWhereCacheKey($where);
//        $rows = Cache::get($cacheFile);
        //分析订单中哪些商品已返,哪些没返
        $ModelLogs = new CommissionReturnLogsModel();
        $fields = ['billing', 'province', 'city', 'product_name', 'product_id', 'tax', 'commission_money', 'commission_tax_money'];
        $rows = [];
        foreach ($ModelLogs->searchWhere($where)->select($fields)->cursor() as $row) {
            $province = str_replace('省', '', $row->province);
            $city = str_replace('市', '', $row->city);
            $md5sum = md5($row->billing . $row->product_id . $province . $city);
            if (!isset($rows[$md5sum])) {
                $rows[$md5sum] = $row;
            } else {
                //统计账期应付金额
                $rows[$md5sum]['commission_money'] += $row->commission_money;
                $rows[$md5sum]['commission_tax_money'] += $row->commission_tax_money;
            }
            //这几项,都在下面计算
            $rows[$md5sum]['rate'] = 0;
            $rows[$md5sum]['remaining'] = 0;
            $rows[$md5sum]['remark'] = '请填入帐期消耗';
        }
        //帐期输入资料
        $ModelCommissionReturn = new CommissionReturnModel();
        foreach ($ModelCommissionReturn->searchWhere($where)->cursor() as $row) {
            $province = str_replace('省', '', $row->province);
            $city = str_replace('市', '', $row->city);
            $md5sum = md5($row->billing . $row->product_id . $province . $city);
            if (!isset($rows[$md5sum])) {
                $rows[$md5sum] = $row->toArray();
                $rows[$md5sum]['tax'] = 0;
                $rows[$md5sum]['commission_money'] = 0;
                $rows[$md5sum]['commission_tax_money'] = 0;
                $rows[$md5sum]['remark'] = '请导入帐期佣金';
            } else {
                $rows[$md5sum]['received_money'] = $row->received_money;
                $rows[$md5sum]['deplete_money'] = $row->deplete_money;
                $rows[$md5sum]['remark'] = $row->remark;
            }
            $rows[$md5sum]['rate'] = 0;
            if ($row->deplete_money > 0) {
                $rows[$md5sum]['rate'] = round($row->received_money / $row->deplete_money * 100, 1);
            }
            // 计算剩余:月应付-回款金额
            $rows[$md5sum]['remaining'] = 0;
            if (isset($rows[$md5sum]['commission_money'])) {
                $rows[$md5sum]['remaining'] = $rows[$md5sum]['commission_money'] - $rows[$md5sum]['received_money'];
            }
        }
//        Cache::put($cacheFile, $rows, 360);
        return $this->returnMsg(200, '无订单数据', $rows, 0);
    }

    //推广订单成本
    public function sumAnchorCost($params, $authorIds)
    {
        $where = [];
        if (isset($params['dateRange']) && !empty($params['dateRange'])) {
            $params['dateRange'] = [date('Y-m-d', strtotime($params['dateRange'][0])), date('Y-m-d', strtotime($params['dateRange'][1])) . ' 23:59:59'];
            $where['between']['created_at'] = $params['dateRange'];
        }
        if (!empty($authorIds)) {
            $where['in']['author_id'] = array_unique($authorIds);
        }
        //关联主播时间数据
        $ModelAnchorWorks = new AnchorWorksModel();
//        查询开播数据
        return $ModelAnchorWorks->searchWhere($where)->sum('cost');
    }


}
